﻿using System;
using System.Reflection;
using System.Threading.Tasks;
using System.Collections;
using System.Collections.Generic;

using MyCtp;
using MyCtp.Model;

namespace MyCtp.Api
{
    /// <summary>
    /// 交易操作接口(所有事件为异步调用)
    /// </summary>
    public class TradeApi
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="brokerid">经纪商ID</param>
        /// <param name="userid">账号</param>
        /// <param name="pwd">密码</param>
        /// <param name="frontAddresses">前置机地址</param>
        public TradeApi(string brokerid, string userid, string pwd, string[] fronts)
        {
            brokerID = brokerid;
            userID   = userid;
            password = pwd;

            Init(fronts);
        }

        /// <summary>
        /// 释放交易接口对象
        /// </summary>
        public void Release()
        {
            ctpTdApi.Release();
        }


        /******************************** 交易函数 ********************************/

        /// <summary>
        /// 买入开仓
        /// </summary>
        /// <param name="instrumentID">合约代码</param>
        /// <param name="price">价格</param>
        /// <param name="volume">数量</param>
        public void Buy(string instrumentID, double price, int volume)
        {
            OrderInsert(DirectionEnum.Buy, MyOffsetFlag.Open, instrumentID, price, volume);
        }

        /// <summary>
        /// 卖出开仓
        /// </summary>
        /// <param name="instrumentID">合约代码</param>
        /// <param name="price">价格</param>
        /// <param name="volume">数量</param>
        public void Sell(string instrumentID, double price, int volume)
        {
            OrderInsert(DirectionEnum.Sell, MyOffsetFlag.Open, instrumentID, price, volume);
        }

        /// <summary>
        /// 平仓
        /// </summary>
        public void Close(DirectionEnum direction, string instrumentID, double price, int volume)
        {
            OrderInsert(direction, MyOffsetFlag.Close, instrumentID, price, volume);
        }

        /// <summary>
        /// 平今仓
        /// </summary>
        public void CloseToday(DirectionEnum direction, string instrumentID, double price, int volume)
        {
            OrderInsert(direction, MyOffsetFlag.CloseToday, instrumentID, price, volume);
        }


        /******************************** 查询函数 ********************************/

        /// <summary>
        /// 请求查询成交
        /// </summary>
        public int QryTrade()
        { 
            CThostFtdcQryTradeField field = new CThostFtdcQryTradeField();

            field.BrokerID      = brokerID;
            field.InvestorID    = userID;

            return ctpTdApi.ReqQryTrade(field, requestID++);
        }

        /// <summary>
        /// 请求查询报单
        /// </summary>
        public int QryOrder()
        { 
            CThostFtdcQryOrderField field = new CThostFtdcQryOrderField();

            field.BrokerID      = brokerID;
            field.InvestorID    = userID;

            return ctpTdApi.ReqQryOrder(field, requestID++);
        }

        /// <summary>
        /// 查询资金账户
        /// </summary>
        public int QryTradingAccount()
        { 
            CThostFtdcQryTradingAccountField field = new CThostFtdcQryTradingAccountField();

            field.BrokerID   = brokerID;
            field.InvestorID = userID;

            return ctpTdApi.ReqQryTradingAccount(field, requestID++);
        }

        /// <summary>
        /// 查询合约
        /// </summary>
        /// <param name="instrumentID">合约代码（不填则查所有合约）</param>
        public int QryInstrument(string instrumentID)
        {
            CThostFtdcQryInstrumentField field = new CThostFtdcQryInstrumentField();

            field.InstrumentID = instrumentID;

            return ctpTdApi.ReqQryInstrument(field, requestID++);
        }

        /// <summary>
        /// 请求查询投资者持仓
        /// </summary>
        /// <param name="instrumentID">合约代码（不填则查询所有合约的持仓情况）</param>
        public int QryInvestorPosition(string instrumentID = "")
        {
            CThostFtdcQryInvestorPositionField field = new CThostFtdcQryInvestorPositionField();

            field.BrokerID = brokerID;
            field.InvestorID = userID;
            field.InstrumentID = instrumentID;

            return ctpTdApi.ReqQryInvestorPosition(field, requestID++);
        }

        /// <summary>
        /// 请求查询投资者持仓明细
        /// </summary>
        /// <param name="instrumentID">合约代码（不填则查询所有合约的持仓情况）</param>
        public int QryInvestorPositionDetail(string instrumentID = "")
        {
            CThostFtdcQryInvestorPositionDetailField field = new CThostFtdcQryInvestorPositionDetailField();

            field.BrokerID = brokerID;
            field.InvestorID = userID;
            field.InstrumentID = instrumentID;

            return ctpTdApi.ReqQryInvestorPositionDetail(field, requestID++);
        }

        /// <summary>
        /// 请求查询投资者组合持仓明细
        /// </summary>
        /// <param name="instrumentID">合约代码（不填则查询所有合约的持仓情况）</param>
        public int QryInvestorPositionCombineDetail(string combInstrumentID = "")
        {
            CThostFtdcQryInvestorPositionCombineDetailField field = new CThostFtdcQryInvestorPositionCombineDetailField();

            field.BrokerID = brokerID;
            field.InvestorID = userID;
            field.CombInstrumentID = combInstrumentID;

            return ctpTdApi.ReqQryInvestorPositionCombineDetail(field, requestID++);
        }

        /// <summary>
        /// 查询投资者结算确认结果
        /// </summary>
        public int QrySettlementConfirmInfo()
        {
            CThostFtdcQrySettlementInfoConfirmField field = new CThostFtdcQrySettlementInfoConfirmField();

            field.BrokerID = brokerID;
            field.InvestorID = userID;

            return ctpTdApi.ReqQrySettlementInfoConfirm(field, requestID++);
        }

        /// <summary>
        /// 确认投资者结算
        /// </summary>
        public int ReqSettlementConfirmInfo()
        {
            CThostFtdcSettlementInfoConfirmField field = new CThostFtdcSettlementInfoConfirmField();

            field.BrokerID = brokerID;
            field.InvestorID = userID;
            field.ConfirmDate = DateTime.Now.ToString("yyyyMMdd");
            field.ConfirmTime = DateTime.Now.ToString("HH:mm:ss");

            return ctpTdApi.ReqSettlementInfoConfirm(field, requestID++);
        }


        /******************************** Private ********************************/

        #region variable

        /// <summary>
        /// 行情数据接口对象
        /// </summary>
        private CtpTdApi ctpTdApi;

        /// <summary>
        /// 请求序号
        /// </summary>
        private int requestID = 0;

        /// <summary>
        /// 经纪商ID
        /// </summary>
        private string brokerID;

        /// <summary>
        /// 账号
        /// </summary>
        private string userID;
        
        /// <summary>
        /// 密码
        /// </summary>
        private string password;

        /// <summary>
        /// 前置编号
        /// </summary>
        private int frontID;

        /// <summary>
        /// 会话编号
        /// </summary>
        private int sessionID;

        /// <summary>
        /// 报单引用
        /// </summary>
        private int orderRef;

        /// <summary>
        /// 交易所代码
        /// </summary>
        private string exchangeID;

        /// <summary>
        /// 报单编号
        /// </summary>
        private string orderSysID;

        #endregion

        /// <summary>
        /// 报单录入（开仓/平仓，买入/卖出）
        /// </summary>
        /// <param name="direction">买卖方向</param>
        /// <param name="offsetFlag">开仓/平仓(MyOffsetFlag)</param>
        /// <param name="instrumentID">合约代码</param>
        /// <param name="price">价格</param>
        /// <param name="volume">数量</param>
        private void OrderInsert(DirectionEnum direction, string offsetFlag, string instrumentID, double price, int volume)
        {
            CThostFtdcInputOrderField order = new CThostFtdcInputOrderField();

            order.BrokerID              = this.brokerID;
            order.UserID                = this.userID;
            order.InvestorID            = this.userID;

            order.Direction             = direction;
            order.LimitPrice            = price;
            order.VolumeTotalOriginal   = volume;
            order.InstrumentID          = instrumentID;

            order.CombOffsetFlag        = offsetFlag;
            order.CombHedgeFlag         = MyHedgeFlag.Speculation;

            order.StopPrice             = 0;
            order.MinVolume             = 1;
            order.TimeCondition         = TimeConditionEnum.GFD;
            order.OrderPriceType        = OrderPriceTypeEnum.LimitPrice;
            order.VolumeCondition       = VolumeConditionEnum.AV;
            order.ContingentCondition   = ContingentConditionEnum.Immediately;

            order.RequestID             = requestID;
            order.OrderRef              = (this.orderRef++).ToString();

            order.IsAutoSuspend         = 0;
            order.UserForceClose        = 0;
            order.ForceCloseReason      = ForceCloseReasonEnum.NotForceClose;

            ctpTdApi.ReqOrderInsert(order, requestID++);
        }

        /// <summary>
        /// 报单操作（修改/撤销委托）
        /// </summary>
        /// <param name="action">操作类型呢（修改/删除）</param>
        /// <param name="orderRef">报单引用</param>
        /// <param name="instrumentID">合约代码</param>
        /// <param name="price">价格</param>
        /// <param name="volume">数量</param>
        private void OrderAction(ActionFlagEnum action, string orderRef, string instrumentID, double price, int volume)
        {
            CThostFtdcInputOrderActionField field = new CThostFtdcInputOrderActionField();

            field.BrokerID      = brokerID;
            field.InvestorID    = userID;
            field.UserID        = userID;
            field.InstrumentID  = instrumentID;

            field.ActionFlag    = action;
            field.LimitPrice    = price;
            field.VolumeChange  = volume;

            //报单在CTP平台用的定位
            field.FrontID       = frontID;
            field.SessionID     = sessionID;
            field.OrderRef      = orderRef;

            //报单在交易所用的定位
            field.ExchangeID    = "";
            field.OrderSysID    = "";

            //field.OrderActionRef = 0;
            //field.RequestID     = 0;

            ctpTdApi.ReqOrderAction(field, requestID++);
        }


        /******************************** 回调事件 ********************************/

        /// <summary>
        /// 初始化TdApi对象并注册回调事件
        /// </summary>
        private void Init(string[] fronts)
        {
            ctpTdApi = new CtpTdApi();

            //注册前置机地址
            foreach (string front in fronts)
                ctpTdApi.RegisterFront(front);

            ctpTdApi.CtpTdEvents.OnFrontConnected += this.OnFrontConnected;                //连接请求响应
            ctpTdApi.CtpTdEvents.OnRspUserLogin   += this.OnRspUserLogin;                  //用户登录响应

            ctpTdApi.CtpTdEvents.OnRtnOrder += this.OnRtnOrder;                            //报单通知
            ctpTdApi.CtpTdEvents.OnRtnTrade += this.OnRtnTrade;                            //成交通知
            ctpTdApi.CtpTdEvents.OnRtnTradingNotice += this.OnRtnTradingNotice;            //交易通知

            ctpTdApi.CtpTdEvents.OnRspOrderInsert += this.OnRspOrderInsert;                //报单录入请求响应
            ctpTdApi.CtpTdEvents.OnRspOrderAction += this.OnRspOrderAction;                //报单操作请求响应

            ctpTdApi.CtpTdEvents.OnErrRtnOrderInsert += this.OnErrRtnOrderInsert;          //报单录入错误回报
            ctpTdApi.CtpTdEvents.OnErrRtnOrderAction += this.OnErrRtnOrderAction;          //报单操作错误回报

            ctpTdApi.CtpTdEvents.OnRspQryInstrument      += this.OnRspQryInstrument;       //请求查询合约响应
            ctpTdApi.CtpTdEvents.OnRspQryDepthMarketData += this.OnRspQryDepthMarketData;  //请求查询行情响应

            ctpTdApi.CtpTdEvents.OnRspQryOrder += this.OnRspQryOrder;                      //请求查询报单响应
            ctpTdApi.CtpTdEvents.OnRspQryTrade += this.OnRspQryTrade;                      //请求查询成交响应
            ctpTdApi.CtpTdEvents.OnRspQryTradingAccount += this.OnRspQryTradingAccount;    //请求查询资金账户响应

            ctpTdApi.CtpTdEvents.OnRspQrySettlementInfo        += this.OnRspQrySettlementInfo;         //查询投资者结算结果响应
            ctpTdApi.CtpTdEvents.OnRspSettlementInfoConfirm    += this.OnRspSettlementInfoConfirm;     //确认投资者结算结果响应
            ctpTdApi.CtpTdEvents.OnRspQrySettlementInfoConfirm += this.OnRspQrySettlementInfoConfirm;  //请求查询结算信息确认响应

            ctpTdApi.CtpTdEvents.OnRspQryInvestor += this.OnRspQryInvestor;                                            //请求查询投资者响应
            ctpTdApi.CtpTdEvents.OnRspQryInvestorPosition += this.OnRspQryInvestorPosition;                            //请求查询投资者持仓响应
            ctpTdApi.CtpTdEvents.OnRspQryInvestorPositionDetail += this.OnRspQryInvestorPositionDetail;                //请求查询投资者持仓明细响应
            ctpTdApi.CtpTdEvents.OnRspQryInvestorPositionCombineDetail += this.OnRspQryInvestorPositionCombineDetail;  //请求查询投资者组合持仓明细响应

            ctpTdApi.CtpTdEvents.OnRtnInstrumentStatus += this.OnRtnInstrumentStatus;       //合约交易状态通知

            ctpTdApi.SubscribePrivateTopic(1);
            ctpTdApi.SubscribePublicTopic(1);

            ctpTdApi.Init();
            Task task = Task.Factory.StartNew(ctpTdApi.Join);
        }


        //连接请求响应
        void OnFrontConnected()
        {
            CThostFtdcReqUserLoginField loginField = new CThostFtdcReqUserLoginField();

            loginField.BrokerID = brokerID;
            loginField.UserID   = userID;
            loginField.Password = password;

            ctpTdApi.ReqUserLogin(loginField, requestID++);
        }

        //用户登录请求响应(确认结算信息)
        void OnRspUserLogin(CThostFtdcRspUserLoginField rspUserLoginfield, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            if (rspUserLoginfield.TradingDay != "")
            {
                frontID   = rspUserLoginfield.FrontID;
                sessionID = rspUserLoginfield.SessionID;
                orderRef  = int.Parse(rspUserLoginfield.MaxOrderRef);

                //查询并确认结算信息
                QrySettlementConfirmInfo();
            }
        }

        /// <summary>
        /// 报单通知
        /// </summary>
        public event OnRtnOrderDelegate RtnOrder;
        public delegate void OnRtnOrderDelegate(CThostFtdcOrderField pOrder);
        
        void OnRtnOrder(CThostFtdcOrderField pOrder)
        {
            if (RtnOrder != null) 
                RtnOrder.BeginInvoke(pOrder, null, null);
        }

        /// <summary>
        /// 成交通知
        /// </summary>
        public event OnRtnTradeDelegate RtnTrade;
        public delegate void OnRtnTradeDelegate(CThostFtdcTradeField pTrade);

        void OnRtnTrade(CThostFtdcTradeField pTrade)
        {
            if (RtnTrade != null) 
                RtnTrade.BeginInvoke(pTrade, null, null);
        }

        /// <summary>
        /// 交易通知
        /// </summary>
        public event OnRtnTradingNoticeDelegate RtnTradingNotice;
        public delegate void OnRtnTradingNoticeDelegate(CThostFtdcTradingNoticeInfoField pTradingNoticeInfo);

        void OnRtnTradingNotice(CThostFtdcTradingNoticeInfoField pTradingNoticeInfo)
        {
            if (RtnTradingNotice != null)
                RtnTradingNotice.BeginInvoke(pTradingNoticeInfo, null, null);
        }

        /// <summary>
        /// 报单录入请求响应
        /// </summary>
        public event OnRspOrderInsertDelegate RspOrderInsert;
        public delegate void OnRspOrderInsertDelegate(CThostFtdcInputOrderField pInputOrder, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast);

        void OnRspOrderInsert(CThostFtdcInputOrderField pInputOrder, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            if (RspOrderInsert != null) 
                RspOrderInsert.BeginInvoke(pInputOrder, pRspInfo, nRequestID, bIsLast, null, null);
        }

        /// <summary>
        /// 报单操作请求响应
        /// </summary>
        public event OnRspOrderActionDelegate RspOrderAction;
        public delegate void OnRspOrderActionDelegate(CThostFtdcInputOrderActionField pInputOrderAction, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast);
        
        void OnRspOrderAction(CThostFtdcInputOrderActionField pInputOrderAction, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            if (RspOrderAction != null) 
                RspOrderAction.BeginInvoke(pInputOrderAction, pRspInfo, nRequestID, bIsLast, null, null);
        }

        /// <summary>
        /// 报单录入错误回报
        /// </summary>
        public event OnErrRtnOrderInsertDelegate ErrRtnOrderInsert;
        public delegate void OnErrRtnOrderInsertDelegate(CThostFtdcInputOrderField pInputOrder, CThostFtdcRspInfoField pRspInfo);

        void OnErrRtnOrderInsert(CThostFtdcInputOrderField pInputOrder, CThostFtdcRspInfoField pRspInfo)
        {
            if (ErrRtnOrderInsert != null) 
                ErrRtnOrderInsert.BeginInvoke(pInputOrder, pRspInfo, null, null);
        }

        /// <summary>
        /// 报单操作错误回报
        /// </summary>
        public event OnErrRtnOrderActionDelegate ErrRtnOrderAction;
        public delegate void OnErrRtnOrderActionDelegate(CThostFtdcOrderActionField pOrderAction, CThostFtdcRspInfoField pRspInfo);

        void OnErrRtnOrderAction(CThostFtdcOrderActionField pOrderAction, CThostFtdcRspInfoField pRspInfo)
        {
            if (ErrRtnOrderAction != null) 
                ErrRtnOrderAction.BeginInvoke(pOrderAction, pRspInfo, null, null);
        }

        /// <summary>
        /// 请求查询合约响应
        /// </summary>
        public event OnRspQryInstrumentDelegate RspQryInstrument;
        public delegate void OnRspQryInstrumentDelegate(CThostFtdcInstrumentField pInstrument, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast);

        void OnRspQryInstrument(CThostFtdcInstrumentField pInstrument, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            if (RspQryInstrument != null) 
                RspQryInstrument.BeginInvoke(pInstrument, pRspInfo, nRequestID, bIsLast, null, null);
        }

        /// <summary>
        /// 请求查询报单响应
        /// </summary>
        public event OnRspQryOrderDelegate RspQryOrder;
        public delegate void OnRspQryOrderDelegate(CThostFtdcOrderField pOrder, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast);

        void OnRspQryOrder(CThostFtdcOrderField pOrder, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            if (RspQryOrder != null)
                RspQryOrder.BeginInvoke(pOrder, pRspInfo, nRequestID, bIsLast, null, null);
        }

        /// <summary>
        /// 请求查询成交响应
        /// </summary>
        public event OnRspQryTradeDelegate RspQryTrade;
        public delegate void OnRspQryTradeDelegate(CThostFtdcTradeField pTrade, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast);

        void OnRspQryTrade(CThostFtdcTradeField pTrade, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            if (RspQryTrade != null)
                RspQryTrade.BeginInvoke(pTrade, pRspInfo, nRequestID, bIsLast, null, null);
        }

        /// <summary>
        /// 请求查询资金账户响应
        /// </summary>
        public event OnRspQryTradingAccountDelegate RspQryTradingAccount;
        public delegate void OnRspQryTradingAccountDelegate(CThostFtdcTradingAccountField pTradingAccount, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast);

        void OnRspQryTradingAccount(CThostFtdcTradingAccountField pTradingAccount, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            if( RspQryTradingAccount != null ) 
                RspQryTradingAccount.BeginInvoke(pTradingAccount, pRspInfo, nRequestID, bIsLast, null, null);
        }

        /// <summary>
        /// 查询结算信息响应
        /// </summary>
        public event OnRspQrySettlementInfoDelegate RspQrySettlementInfo;
        public delegate void OnRspQrySettlementInfoDelegate(CThostFtdcSettlementInfoField pSettlementInfo, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast);

        void OnRspQrySettlementInfo(CThostFtdcSettlementInfoField pSettlementInfo, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            if (RspQrySettlementInfo != null) 
                RspQrySettlementInfo.BeginInvoke(pSettlementInfo, pRspInfo, nRequestID, bIsLast, null, null);
        }

        //查询投资者结算确认结果响应
        void OnRspQrySettlementInfoConfirm(CThostFtdcSettlementInfoConfirmField pSettlementInfoConfirm, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            //如果结果为空则说明没有确认过结果
            if (bIsLast && pSettlementInfoConfirm == null)
                ReqSettlementConfirmInfo();
        }

        /// <summary>
        /// 确认投资者结算结果响应
        /// </summary>
        public event OnRspSettlementInfoConfirmDelegate RspSettlementInfoConfirm;
        public delegate void OnRspSettlementInfoConfirmDelegate(CThostFtdcSettlementInfoConfirmField pSettlementInfoConfirm, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast);

        void OnRspSettlementInfoConfirm(CThostFtdcSettlementInfoConfirmField pSettlementInfoConfirm, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {          
            if (RspSettlementInfoConfirm != null) 
                RspSettlementInfoConfirm.BeginInvoke(pSettlementInfoConfirm, pRspInfo, nRequestID, bIsLast, null, null);
        }

        /// <summary>
        /// 请求查询投资者响应
        /// </summary>
        public event OnRspQryInvestorDelegate RspQryInvestor;
        public delegate void OnRspQryInvestorDelegate(CThostFtdcInvestorField pInvestor, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast);

        void OnRspQryInvestor(CThostFtdcInvestorField pInvestor, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            if (RspQryInvestor != null) 
                RspQryInvestor.BeginInvoke(pInvestor, pRspInfo, nRequestID, bIsLast, null, null);
        }

        /// <summary>
        /// 请求查询投资者持仓响应
        /// </summary>
        public event OnRspQryInvestorPositionDelegate RspQryInvestorPosition;
        public delegate void OnRspQryInvestorPositionDelegate(CThostFtdcInvestorPositionField pInvestorPosition, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast);

        void OnRspQryInvestorPosition(CThostFtdcInvestorPositionField pInvestorPosition, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            if (RspQryInvestorPosition != null) 
                RspQryInvestorPosition.BeginInvoke(pInvestorPosition, pRspInfo, nRequestID, bIsLast, null, null);
        }

        /// <summary>
        /// 请求查询投资者持仓明细响应
        /// </summary>
        public event OnRspQryInvestorPositionDetailDelegate RspQryInvestorPositionDetail;
        public delegate void OnRspQryInvestorPositionDetailDelegate(CThostFtdcInvestorPositionDetailField pInvestorPositionDetail, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast);

        void OnRspQryInvestorPositionDetail(CThostFtdcInvestorPositionDetailField pInvestorPositionDetail, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            if (RspQryInvestorPositionDetail != null) 
                RspQryInvestorPositionDetail.BeginInvoke(pInvestorPositionDetail, pRspInfo, nRequestID, bIsLast, null, null);
        }

        /// <summary>
        /// 请求查询投资者组合持仓明细响应
        /// </summary>
        public event OnRspQryInvestorPositionCombineDetailDelegate RspQryInvestorPositionCombineDetail;
        public delegate void OnRspQryInvestorPositionCombineDetailDelegate(CThostFtdcInvestorPositionCombineDetailField pInvestorPositionCombineDetail, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast);

        void OnRspQryInvestorPositionCombineDetail(CThostFtdcInvestorPositionCombineDetailField pInvestorPositionCombineDetail, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            if (RspQryInvestorPositionCombineDetail != null) 
                RspQryInvestorPositionCombineDetail.BeginInvoke(pInvestorPositionCombineDetail, pRspInfo, nRequestID, bIsLast, null, null);
        }

        /// <summary>
        /// 请求查询行情响应
        /// </summary>
        public event OnRspQryDepthMarketDataDelegate RspQryDepthMarketData;
        public delegate void OnRspQryDepthMarketDataDelegate(CThostFtdcDepthMarketDataField pDepthMarketData, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast);

        void OnRspQryDepthMarketData(CThostFtdcDepthMarketDataField pDepthMarketData, CThostFtdcRspInfoField pRspInfo, int nRequestID, bool bIsLast)
        {
            if (RspQryDepthMarketData != null) 
                RspQryDepthMarketData.BeginInvoke(pDepthMarketData, pRspInfo, nRequestID, bIsLast, null, null);
        }

        /// <summary>
        /// 合约交易状态通知
        /// </summary>
        public event OnRtnInstrumentStatusDelegate RtnInstrumentStatus;
        public delegate void OnRtnInstrumentStatusDelegate(CThostFtdcInstrumentStatusField pInstrumentStatus);

        void OnRtnInstrumentStatus(CThostFtdcInstrumentStatusField pInstrumentStatus)
        {
            if (RtnInstrumentStatus != null)
                RtnInstrumentStatus.BeginInvoke(pInstrumentStatus, null, null);
        }

    }
}
